﻿using System;
using System.Collections.Generic;
using System.Linq;
using Jink.Core.Converters.Context;
using XenoGears.Reflection;
using XenoGears.Functional;
using XenoGears.Assertions;

namespace Jink.Core.Converters
{
    public static partial class Converter
    {
        public static TOutput Convert<TOutput>(this Object input)
        {
            return input.Convert<TOutput>(new Dictionary<String, Object>());
        }

        public static TOutput Convert<TOutput>(this Object input, Object pbag)
        {
            return input.Convert<TOutput>(pbag.ToPropertyBag());
        }

        public static TOutput Convert<TOutput>(this Object input, IDictionary<String, Object> cookies)
        {
            return (TOutput)input.Convert(typeof(TOutput), cookies);
        }

        public static Object Convert(this Object input, Type outputType)
        {
            return input.Convert(outputType, new Dictionary<String, Object>());
        }

        public static Object Convert(this Object input, Type outputType, Object pbag)
        {
            return input.Convert(outputType, pbag.ToPropertyBag());
        }

        public static Object Convert(this Object input, Type outputType, IDictionary<String, Object> cookies)
        {
            return input.Convert(input.GetType(), outputType, cookies);
        }

        public static TOutput Convert<TInput, TOutput>(this Object input)
        {
            return input.Convert<TInput, TOutput>(new Dictionary<String, Object>());
        }

        public static TOutput Convert<TInput, TOutput>(this Object input, Object pbag)
        {
            return input.Convert<TInput, TOutput>(pbag.ToPropertyBag());
        }

        public static TOutput Convert<TInput, TOutput>(this Object input, IDictionary<String, Object> cookies)
        {
            return (TOutput)input.Convert(typeof(TInput), typeof(TOutput), cookies);
        }

        public static Object Convert(this Object input, Type inputType, Type outputType)
        {
            return input.Convert(inputType, outputType, new Dictionary<String, Object>());
        }

        public static Object Convert(this Object input, Type inputType, Type outputType, Object pbag)
        {
            return input.Convert(inputType, outputType, pbag.ToPropertyBag());
        }

        public static Object Convert(this Object input, Type inputType, Type outputType, IDictionary<String, Object> cookies)
        {
            var cce = new ConversionContextEntry(inputType, input, new {name = "anonymous"});
            var result = Convert(cce.MkArray(), "anonymous".Map(outputType));
            return result.AssertNotNull().Single().Value;
        }
    }
}
